/*
Copyright (C) 2008 Matthew Perry

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This libary/program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using BaseTools.Helpers;
using System.IO;
using System.Text;

namespace BaseTools.Configuration.Parsers
{
	using GenericSection = Dictionary<string, string>; 
	using GenericApplication = Dictionary<string, Dictionary<string, string>>;
	
	/// <summary>
	/// Reader/writer for an ini
	/// </summary>
	public class IniConfig : IIni
	{
		/// <summary>
		/// Creates a new ini reader
		/// </summary>
		public IniConfig()
		{
		}
		
		/// <summary>
		/// Save the ini to a file
		/// </summary>
		/// <param name="filename">The filename</param>
		/// <param name="lst">The GenericApplication to write</param>
		public void SaveConfiguration(string filename, GenericApplication lst)
		{
			File.WriteAllText(IOHelper.CleanPath(filename), WriteConfiguration(lst));
		}
		
		/// <summary>
		/// Save the ini to a string
		/// </summary>
		/// <param name="lst">The GenericApplication to write</param>
		/// <returns>A string representing the GenericApplication</returns>
		public string WriteConfiguration(GenericApplication lst)
		{
			StringBuilder data = new StringBuilder();
			
			foreach(KeyValuePair<string, GenericSection> kvp in lst)
			{
				data.Append('[').Append(kvp.Key).Append("]\n");
				WriteSection(kvp.Value, data);
				data.Append('\n');
			}
			
			return data.ToString();
		}
		
		private void WriteSection(GenericSection sec, StringBuilder data)
		{
			foreach(KeyValuePair<string, string> kvp in sec)
			{
				data.Append(kvp.Key).Append('=').Append(kvp.Value).Append('\n');
			}
		}
		
		/// <summary>
		/// Load the ini from a file
		/// </summary>
		/// <param name="filename">The filename</param>
		/// <returns>A GenericApplication interpreted from the file</returns>
		public GenericApplication LoadConfiguration(string filename)
		{
			return ReadConfiguration(File.ReadAllText(IOHelper.CleanPath(filename)));
		}
		
		/// <summary>
		/// Load the configuration from a string
		/// </summary>
		/// <param name="data">The data</param>
		/// <returns>A GenericApplication interpreted from the string</returns>
		public GenericApplication ReadConfiguration(string data)
		{
			string newdata;
			newdata = data.Replace("\r\n", "\n").Replace("\r", "").Replace("\t", "");
			
			GenericApplication ga = new GenericApplication();
			GenericSection cs = null;
			
			string[] lines = newdata.Split('\n');
			
			foreach(string linex in lines)
			{
				string line = linex.Trim();
				
				if (line.Length > 0 && !line.StartsWith(";"))
				{
					if (line.StartsWith("[") && line.EndsWith("]"))
					{
						string secn = line.Substring(1, line.Length-2);
						
						if (secn.Length > 0)
						{
							if (ga.ContainsKey(secn))
							{
								cs = ga[secn];
							}
							else
							{
								cs = new GenericSection();
								
								ga.Add(secn, cs);
							}
								 
						}
					}
					else
					{
						if (cs != null)
						{
							string[] kv = line.Split(new char[] {'='}, 2);
							
							if (kv.Length == 1)
								kv = new string[] {kv[0], ""};
							
							kv[0] = kv[0].Trim();
							kv[1] = kv[1].Trim();
							
							if (!cs.ContainsKey(kv[0]))
							{
								cs.Add(kv[0], kv[1]);
							}
						}
					}
				}
			}
			
			return ga;
		}
	}
}
